/**
 * @file lv_watch.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "lv_watch.h"
#include "../../board.h"
#if USE_TOUCH_TRACKER
#include "../lv_drivers/indev/touch_tracker.h"
#endif

#if USE_WATCH_SPORT
//can do something only for watch_aport
#endif

#if USE_LV_WATCH != 0

#include <stdio.h>

/*********************
 *      DEFINES
 *********************/
#ifndef USE_POWER_ON_GIF
#define USE_POWER_ON_GIF 0
#endif

/**********************
 *      TYPEDEFS
 **********************/
static watch_info_t * watch_info;
lv_task_t * lowbattery_task_p;
#if USE_LV_WATCH_SIMCHECK
lv_task_t * checksim_task_p = NULL;
#endif
static MMI_MODEM_PIN_STATUS_TYPE pintype = MMI_MODEM_PIN_DISABLED;
static bool watch_ui_wake_up_flag = false; // wake up flag other than key and alarm
static lv_task_t * watch_ui_wake_up_task = NULL;
bool gcf_test = false;
static lv_task_t * monitor_task = NULL;
static uint8_t suspend_reason = WATCH_SUSPEND_UI;
static bool is_wakeup_lcd = true;
#if USE_LV_WATCH_SD_AUTO_MOUNT != 0
static lv_task_t * sd_mount_task = NULL;
static int usb_conn_status = 0;
#endif
typedef struct {
    lv_watch_Activity_Id_t act;
    bool top;
}lv_watch_suspend_t;

static lv_ll_t suspend_ll;

/**********************
 *  STATIC PROTOTYPES
 **********************/
#if USE_POWER_ON_GIF != 0
static void main_task(lv_task_t * param);
#endif
static lv_obj_t * watch_create(bool silentReset);
static void watch_powerup_onkey_common_process(void);
static void watch_powerup_alarm_common_process(void);
static void watch_powerup_silent_reset_process(void);
static void watch_powerup_charging_common_process(void);
static void watch_start_activity_monitor_task(void);
static void watch_shut_down(hal_rtc_t * poweron_time);
static void watch_normal_charging_status_change(VOID * para);
#if USE_LV_WATCH_SD_AUTO_MOUNT != 0
static void watch_start_sd_mount_task(void);
#endif
static void watch_suspend_mng_init(void);
static bool watch_get_suspend_enable(void);

/**********************
 *  STATIC VARIABLES
 **********************/
#if USE_POWER_ON_GIF != 0
LV_IMG_DECLARE(anim_power_on);
static lv_task_t * main_task_p;
#endif
static bool watch_ready = false;
static bool watch_lcd_status = true;  // true means wakeup, false means sleep
static bool watch_sleep_lcd_only = false;
static bool watch_silent_reset = false;
static bool watch_ambient = false;
static bool watch_alarm_flag = false;

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/
void watch_restart_req(void)
{
    watch_set_ready_state(false);

    lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_POWER_OFF_CHARGING);

    if(activity_obj) {
        lv_obj_t * watch_obj;
        lv_power_off_charging_ext_t * charging_ext = NULL;

        lv_watch_get_child_obj(activity_obj, lv_watch_obj_signal, &watch_obj);
        if(watch_obj) charging_ext = lv_obj_get_ext_attr(watch_obj);
        if(NULL == charging_ext) return;
        if(NULL != charging_ext->battery_task) {
            lv_task_del(charging_ext->battery_task);
            charging_ext->battery_task = NULL;
        }
        lv_watch_png_cache_all_free();

        // delete activity
        lv_watch_activity_ext_t * ext = lv_obj_get_ext_attr(activity_obj);
        if(NULL != ext) {
            ext->prepare_destory(activity_obj);
            lv_obj_del(activity_obj);
            watch_powerup_onkey_common_process();

#if USE_LV_WATCH_MODEM_ADAPTOR
            if(!setting_is_flying_mode()) {
                watch_modem_power_up_req();
            }
#endif
        } else {
            printf("ext is NULL in watch_restart_req!\n");
        }
    } else {
        sos_btn_action(NULL);
    }
}

void watch_power_on_req(void)
{
    HAL_POWERUP_REASON reason = Hal_Powerup_Get_Reason();

#if USE_LV_THEME_WATCH_NIGHT != 0
    lv_theme_t * th = LV_THEME_WATCH_NIGHT_INIT();
    lv_theme_set_act(th);
#endif

    UI_NV_Restroe_Req();

    setting_init();
    phone_init();
    alarm_init();
    phonebook_init();
#if USE_LV_WATCH_VIDEOCALL
    voip_call_init();
#endif
    app_adaptor_shutdown_bind(watch_shut_down);
    Hal_Register_Low_Power_Ind(watch_low_power_ind_cb);
    Hal_Set_Voice_Call_Status(VOICE_CALL_END);

#if USE_LV_WATCH_MODEM_ADAPTOR
    watch_modem_adp_init_req();

#if USE_LV_WATCH_MOBILE_NETWORK
    MMI_Modem_Apn_Info_t *apn_info = mobile_network_get_apn_info();
    watch_modem_set_apn_info(apn_info);
#endif

    bool power_up_req = true;
#if USE_LV_WATCH_POWER_OFF_CHARGING != 0
    if(HAL_POWERUP_BAT == reason || HAL_POWERUP_USB == reason) {
        power_up_req = false;
    }
#endif

    if(power_up_req && !setting_is_flying_mode()) {
        watch_modem_power_up_req();
    }
#endif

#if USE_LV_WATCH_SD_AUTO_MOUNT != 0
    usb_conn_status = Hal_Get_Usb_Status();
#endif

    watch_suspend_mng_init();
    if((HAL_POWERUP_ONKEY == reason) || (HAL_POWERUP_REBOOT == reason)) {
        // unknow is for soft reboot
        watch_powerup_onkey_common_process();
    } else if(HAL_POWERUP_RTC_ALARM == reason) {
        watch_powerup_alarm_common_process();
    } else if(HAL_POWERUP_SILENT_RESET == reason) {
        watch_silent_reset = true;
        watch_powerup_silent_reset_process();
    }
#if USE_LV_WATCH_POWER_OFF_CHARGING != 0
    else if(HAL_POWERUP_BAT == reason || HAL_POWERUP_USB == reason) {
        watch_powerup_charging_common_process();
    }
#endif
    else {
        printf("error mode %d in watch_power_off_req!\n", reason);
    }
}

void watch_default_set(void)
{
#if LV_USE_MULTI_LANG
    lv_lang_set_text_func(lang_get_text_by_id);
#endif
    /*set background image*/
    watch_info->bg = ICON_BACKGROUND;
}

void * watch_get_bg(void)
{
    if(watch_info == NULL)
        return NULL;
    return watch_info->bg;
}

void * watch_set_bg(const void * src)
{
    watch_info->bg = (void *)src;
    return watch_info->bg;
}

void watch_set_dial_type(watch_dial_type_t dial_type)
{
    //read file system to know dial type
     watch_info->dailtype = dial_type;
}

#if LV_WATCH_SIMULATOR
void show_shutdown_screen(void * para)
{
    lv_obj_t * shutdown_screen = lv_obj_create(lv_layer_top(), NULL);
    lv_obj_set_size(shutdown_screen, LV_HOR_RES, LV_VER_RES);
    lv_obj_set_style_local_bg_color(shutdown_screen, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
}

void power_key(struct _lv_obj_t * obj, lv_event_t event)
{
    if(event == LV_EVENT_CLICKED) {
        printf("this is power key\n");
        lv_watch_go_home();
    } else if (event == LV_EVENT_LONG_PRESSED) {
        shutdown_confirm_btn_action(NULL, LV_EVENT_CLICKED);
        Hal_Timer_Start(1000, show_shutdown_screen, NULL, 0);
    }
}

void option_key(struct _lv_obj_t * obj, lv_event_t event)
{
    if(event == LV_EVENT_CLICKED) {
        printf("this is option key\n");
        setting_create_event_cb(NULL, LV_EVENT_CLICKED);
    }
}
#endif

void watch_poweron_logo(void)
{
    lv_obj_t * activity_obj = NULL;
    lv_watch_activity_ext_t activity_ext;
    memset(&activity_ext, 0, sizeof(lv_watch_activity_ext_t));
    activity_ext.actId = ACT_ID_POWON_LOGO;
    activity_ext.create = NULL;
    activity_ext.prepare_destory = NULL;
    activity_obj = lv_watch_creat_activity_obj(&activity_ext);
    lv_obj_set_style_local_border_side(activity_obj, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_BORDER_SIDE_NONE);
    LV_ASSERT_MEM(activity_obj);

    lv_obj_t * poweron_logo = lv_img_create(activity_obj, NULL);
    lv_img_set_src(poweron_logo, ICON_POWERON_LOGO);
    lv_obj_align(poweron_logo, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0);
    lv_refr_now(NULL);

#if LV_WATCH_SIMULATOR
    extern bool simulator_begin;

    lv_coord_t x_offset = (LV_HOR_RES - LV_HOR_RES_MAX)/2;
    lv_coord_t y_offset = (LV_VER_RES - LV_VER_RES_MAX)/2;

    lv_obj_t * top = lv_img_create(lv_layer_sys(), NULL);
    lv_img_set_src(top, ICON_WATCH_SIMULATOR);
    lv_obj_set_pos(top, 0, 0);

    lv_obj_t * btn_power =  lv_btn_create(top, NULL);
    lv_obj_set_pos(btn_power,  LV_HOR_RES - x_offset, LV_VER_RES_MAX/4);
    lv_obj_set_size(btn_power, LV_HOR_RES/4, LV_HOR_RES/2);
    lv_obj_set_event_cb(btn_power, power_key);
    lv_obj_set_style_local_bg_opa(btn_power, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_0);
    lv_obj_set_style_local_border_opa(btn_power, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_0);
    lv_obj_set_style_local_outline_width(btn_power, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0);

    lv_obj_t * btn_option = lv_btn_create(top, NULL);
    lv_obj_set_size(btn_option, LV_HOR_RES/4, LV_HOR_RES/2);
    lv_obj_align(btn_option, btn_power, LV_ALIGN_OUT_BOTTOM_MID, 0, 0);
    lv_obj_set_event_cb(btn_option, option_key);
    lv_obj_set_style_local_bg_opa(btn_option, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_0);
    lv_obj_set_style_local_border_opa(btn_option, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_0);
    lv_obj_set_style_local_outline_width(btn_option, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0);
    lv_refr_now(NULL);

    simulator_begin = true;
    lv_obj_set_pos(top, x_offset, y_offset);
#endif
}

static void watch_poweron_logo_del(void)
{
    lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_POWON_LOGO);
    if(activity_obj) {
        lv_obj_del(activity_obj);
        lv_img_cache_invalidate_src(ICON_POWERON_LOGO);
    }
}

void watch_low_power_ind_cb(void * para)
{
    (void)para;
    printf("%s\n", __FUNCTION__);

#if !FAKE_BATTERY
    if(0 == Hal_Pm_Get_State()) {
        Hal_Pm_WakeUp();
    } else {
        watch_wakeup_lcd(true);
    }

#endif
}

void watch_low_power_ind_proc(uint32_t bat_percent)
{
    (void)bat_percent;

    watch_shut_down(NULL);
}

/**********************
 *   STATIC FUNCTIONS
 **********************/
static void watch_shut_down(hal_rtc_t * poweron_time)
{
    voice_msg_shut_down();
    alarm_shutdown(poweron_time);
}

static void watch_powerup_onkey_common_process(void)
{
#if USE_POWER_ON_GIF != 0
#ifdef USE_WATCH_LITE
    main_task_p = lv_task_create(main_task, 2000, LV_TASK_PRIO_MID, NULL);
#else
    main_task_p = lv_task_create(main_task, 1000, LV_TASK_PRIO_MID, NULL);
#endif
#else
    watch_create(false);
#if USE_LV_WATCH_MODEM_ADAPTOR
    watch_message_handle_init();
#endif
#if USE_LV_WATCH_ENGINEER_MODE != 0
    watch_modem_pin_status_change_ind(watch_get_pintype());
#endif
#endif

#if USE_LV_DM != 0
    extern void dm_start(void);
    dm_start();
#endif
}

static void watch_powerup_alarm_common_process(void)
{
    watch_create(false);

    /* play alarm tone */
    Hal_NFFS_File_Play_Repeat(AUDIO_ALARM, query_current_volume());
    /* display alarm animation */
    alarm_create(NULL);

#if USE_LV_WATCH_MODEM_ADAPTOR
    watch_message_handle_init();
#endif
}

static void watch_powerup_silent_reset_process(void)
{
    watch_create(true);
#if USE_LV_WATCH_MODEM_ADAPTOR
    watch_message_handle_init();
#endif
}

static void watch_powerup_charging_common_process(void)
{
#if USE_LV_WATCH_MODEM_ADAPTOR
    watch_message_handle_init_for_charging();
#endif

    power_off_charging_create(NULL);
    watch_set_ready_state(true);
    watch_start_activity_monitor_task();
}

#if USE_POWER_ON_GIF != 0
gif_info_t * power_on_gif = NULL;
static void poweron_play_callback(void * result)
{
    //printf("set AudioHAL_SetResBufCnt back to 4\n");
    AudioHAL_SetResBufCnt(4);
}

static void main_task(lv_task_t * task)
{
    lv_obj_t * activity_obj = NULL;
//    LV_AUDIO_DECLARE(audio_power_on);
    lv_task_set_period(main_task_p, 1000);
    if(!power_on_gif) {
        lv_watch_activity_ext_t activity_ext;
        memset(&activity_ext, 0, sizeof(lv_watch_activity_ext_t));
        activity_ext.actId = ACT_ID_ANYOBJ;
        activity_obj = lv_watch_creat_activity_obj(&activity_ext);
        if(activity_obj == NULL) return;
        //lv_obj_set_style(activity_obj, &lv_style_plain);

        power_on_gif = gif_open(activity_obj, "R:/gif/anim_power_on.gif", 1);

        /*fix: when power on, audio is very stuck when ril init*/
        //printf("set AudioHAL_SetResBufCnt 20\n");
        AudioHAL_SetResBufCnt(20);

        Hal_NFFS_File_Play_Onetime("R:/audio/audio_power_on.mid", (HAL_SPEAKER_GAIN)query_current_volume(), poweron_play_callback, 0);
    }

    if(power_on_gif->once_done) {
        gif_close(power_on_gif);
        activity_obj = lv_watch_get_activity_obj(ACT_ID_ANYOBJ);
        if(activity_obj) {
            lv_obj_del(activity_obj);
        }

        power_on_gif = NULL;
        watch_create(false);
#if USE_LV_WATCH_MODEM_ADAPTOR
        watch_message_handle_init();
#endif
#if USE_LV_WATCH_ENGINEER_MODE != 0
        watch_modem_pin_status_change_ind(watch_get_pintype());
#endif
        lv_task_del(main_task_p);
    }
}
#endif

#if USE_LV_WATCH_SIMCHECK
static void simcheck_task(lv_task_t * param)
{
    //no sim and no emergency call is ongoing
    if((false == watch_modem_sim_present_check_req()) &&
       (NULL == phone_get_activity_obj() && NULL == factorymode_get_ext())
       && (WATCH_SHUTDOWN_UNPERFORMED == get_shutdown_performance_flg())
       && (NULL == lv_watch_get_activity_obj(ACT_ID_FACTORY_MODE_MAIN))
       && !setting_is_flying_mode()) {
        watch_modem_sim_soft_reset_req();
        printf("sim soft reset has been run\n");
    }
}
#endif

static void watch_start_wifi_bt_delay(void * para)
{
    (void)para;
#if USE_LV_BLUETOOTH != 0
#if USE_LV_WLAN != 0
    if(!hal_wlan_delay_to_start_bt(bluetooth_start_without_ui)) {
        bluetooth_start_without_ui();
    }
#else
    bluetooth_start_without_ui();
#endif
#endif
}

static lv_obj_t * watch_create(bool silentReset)
{
    watch_poweron_logo_del();

    watch_info = lv_mem_alloc(sizeof(watch_info_t));
    LV_ASSERT_MEM(watch_info);
    if(watch_info == NULL) return NULL;

    watch_default_set();

    watch_start_activity_monitor_task();

    lv_obj_t * obj = launcher_activity_create();

#if USE_LV_WATCH_SD_AUTO_MOUNT != 0
    if((HAL_USB_CONNECTED == Hal_Get_Usb_Status()) && (false == silentReset)) {
        setting_sd_mount_capture_by_usb();
    }
#endif

    lowbattery_task_p = lv_task_create(lowbattery_task, 5000, LV_TASK_PRIO_MID, NULL);

#if USE_LV_WATCH_SIMCHECK
    checksim_task_p = lv_task_create(simcheck_task, WATCH_CHECK_SIM_STATUS_PERIOD, LV_TASK_PRIO_MID, NULL);
#endif

    if(!silentReset) {
        watch_set_ready_state(true);
    }

    if(watch_alarm_flag) {
        watch_set_alarm_flag(false);

        /* play tone start */
        Hal_NFFS_File_Play_Repeat(AUDIO_ALARM, query_current_volume());

        /* display alarm animation */
        alarm_create(NULL);
    }

    Hal_Register_Charger_Status_Ind(watch_normal_charging_status_change);

#if USE_LV_WLAN != 0
    setting_init_mobile_data_switch();
    wlan_init();
#endif

    Hal_Timer_Start(50, watch_start_wifi_bt_delay, NULL, false);
    Hal_Audio_Manage_Init();

#if defined(USE_LV_VAD) && (USE_LV_VAD > 0)
    voice_wakeup_init();
#endif

    return obj;
}

static void watch_wakeup_state_clean(lv_task_t * task)
{
    watch_ui_wake_up_task = NULL;
    watch_ui_wake_up_flag = false;
}

static void watch_wakeup_task_clean(void)
{
    if(NULL != watch_ui_wake_up_task) {
        lv_task_del(watch_ui_wake_up_task);
        watch_ui_wake_up_task = NULL;
    }
    watch_ui_wake_up_flag = false;
}

void watch_wakeup_time_reset(void)
{
    if(watch_ui_wake_up_flag) {
        if(NULL != watch_ui_wake_up_task) lv_task_reset(watch_ui_wake_up_task);
    } else {
        watch_ui_wake_up_flag = true;
        watch_ui_wake_up_task = lv_task_create(watch_wakeup_state_clean,
                                               setting_get_backlight_timeout() * 1000,
                                               LV_TASK_PRIO_HIGHEST,
                                               NULL);
        lv_task_once(watch_ui_wake_up_task);
    }
}

void watch_wake_up_ambient(bool is_suspend)
{
    printf("%s\n",__FUNCTION__);
    dial_ambient_update();
    if(is_suspend)
        Hal_Pm_Resume();
    watch_ambient = true;
    ambient_status_set(true);
    lv_task_ready(monitor_task);
}

void watch_exit_ambient(void)
{
     printf("%s\n", __FUNCTION__);
     #ifndef BUILD_IN_PC_SIMULATOR
     lv_obj_t * ambient_obj = lv_watch_get_activity_obj(ACT_ID_DIAL_AMBIENT);
     dial_ambient_destroy(ambient_obj);
     #endif
     dial_clock_update_immediately();
     Hal_Touch_Wakeup();
     watch_ambient = false;
     ambient_status_set(false);
     Hal_ambient_flag_set(AMBIENT_OFF);
}

// watch is waked up by other event except touch pad
void watch_wake_up(bool wakeup_dev)
{
    printf("%s watch_ui_wake_up_flag %d, wakeup %d, ambient %d\n",
           __FUNCTION__, watch_ui_wake_up_flag, wakeup_dev, Hal_ambient_flag_get());
    if(Hal_ambient_flag_get() == AMBIENT_OFF)
        dial_clock_update_immediately();
    watch_wakeup_time_reset();
    Hal_Pm_Resume();
#if USE_LV_WATCH_SIMCHECK
    if(NULL != checksim_task_p) {
        lv_task_ready(checksim_task_p);
        printf("checksim_task_p is ready\n");
    }
#endif
    if(wakeup_dev) {
        watch_set_lcd_status(true);
    } else {
        watch_set_lcd_status(false);
    }
}

bool watch_get_wakeup_lcd(void)
{
    bool wakeup = is_wakeup_lcd;
    is_wakeup_lcd = true;
    return wakeup;
}
//only wakeup gui but not set lcd on
void watch_disable_wakeup_lcd(void)
{
    is_wakeup_lcd = false;
}

void watch_suspend(lv_task_t * task)
{
    if(watch_silent_reset) {
        watch_silent_reset = false;
        if(Hal_ambient_flag_get() == AMBIENT_ON) {
             //printf("if ambient already enabled in backlight_task , no need do suspend again\n");
             return;
        }
        printf("%s: backlight status %d\n", __FUNCTION__, Hal_Get_Backlight_Status());
        if(0 == Hal_Get_Backlight_Status()) {
            watch_set_lcd_status(false);
        }
    }

    uint16_t period = setting_get_backlight_timeout() * 1000;
    uint32_t inact_time = lv_disp_get_inactive_time(NULL);
    uint32_t wake_up_flag = 0;

    if(watch_ui_wake_up_task) {// add assert for issue #37984
        if(watch_ui_wake_up_task->period != period) {
            printf("fatal error: memory of wakeup task was over write, period is %d\n",
                   watch_ui_wake_up_task->period);
            //not assert, just restart the wakeup task(#50495)
            watch_wakeup_task_clean();
            watch_wakeup_time_reset();
        }
    }

    /*if lcd is off, no calling or wifi, suspend at once. */
    if(!watch_get_lcd_status() || watch_ambient) {
        period = 0;
        watch_ambient = false;
        watch_wakeup_task_clean();
    }

    printf("%s, battery %d, call statue %d, ui wakeup %d, inact_time %d ****************\n",
           __FUNCTION__, Hal_Battery_Get_Status(), call_params.state, watch_ui_wake_up_flag, inact_time);
    uint8_t reason = *(uint8_t *)(task->user_data);
    if((reason == WATCH_SUSPEND_KEY) ||
             ((!watch_ui_wake_up_flag) &&
             (period <= inact_time) &&
             watch_get_suspend_enable())) {
        if(dial_switch_to_ambient()) {
            if(Hal_ambient_flag_get() == AMBIENT_OFF) {
                Hal_ambient_flag_set(AMBIENT_ON);
            }
        }
        if(watch_get_lcd_status()) {
            watch_set_lcd_status(false);
        }

        uint8_t is_suspend = 1;
        static uint8_t suspend_cnt = 0;
        if(watch_sleep_lcd_only) {
            if(Hal_ambient_flag_get() == AMBIENT_ON) {
                if(29 == suspend_cnt ++) {
                    suspend_cnt = 0;
                    is_suspend = 0;
                    wake_up_flag = PM_RESUME_AMBIENT;
                } else {
                    return;
                }
            } else {
                return;
            }
        }

        if(is_suspend)
            wake_up_flag = Hal_Pm_Suspend();

        printf("pm wake up, wake_up_flag 0x%08x ################\n", wake_up_flag);
        if(wake_up_flag & PM_RESUME_ALL) {
            // update dial clock and refresh screen before lcd on
            if((PM_RESUME_UI & wake_up_flag) &&
                    (phone_is_monitor_on() ||false == watch_get_wakeup_lcd())) {
                watch_wake_up(false);
            } else if(PM_RESUME_OVP & wake_up_flag) {
                HAL_CHG_STATUS chg_sts_curr = Hal_Charger_Get_Status();
                if(chg_sts_curr == HAL_CHG_CONNECTED) {
                    printf("Usb vbus on, PM_RESUME_OVP without lcd.\n");
                    watch_wake_up(false);
                } else {
                    watch_wake_up(true);
                }
            } else if((PM_RESUME_AMBIENT & wake_up_flag)) {
                watch_wake_up_ambient(is_suspend);
#if defined(USE_VAD) && (USE_VAD > 0)
            } else if((PM_RESUME_VAD & wake_up_flag)) {
                watch_wake_up(true);
                // sos_create(NULL);
#endif
            } else {
                watch_wake_up(true);
            }
        }
    }
}

void watch_suspend_by_ui(void)
{
    suspend_reason = WATCH_SUSPEND_UI;
    watch_suspend(monitor_task);
}

void watch_suspend_by_key(void)
{
    suspend_reason = WATCH_SUSPEND_KEY;
    watch_suspend(monitor_task);
    suspend_reason = WATCH_SUSPEND_UI;
}

static void watch_start_activity_monitor_task(void)
{
    if(NULL == monitor_task) {
        monitor_task = lv_task_create(watch_suspend, 1000, LV_TASK_PRIO_HIGH, &suspend_reason);
    }
}

#if USE_LV_WATCH_MODEM_ADAPTOR
void watch_modem_power_up_cnf(void)
{
}

void watch_modem_power_off_cnf(void)
{
}
#endif

bool watch_is_ready(void)
{
    return watch_ready;
}

void watch_set_ready_state(bool ready_flag)
{
    watch_ready = ready_flag;
}

static void watch_suspend_mng_init(void)
{
    _lv_ll_init(&suspend_ll, sizeof(lv_watch_suspend_t));
}

/**
 *set suspend enable from app
 *param (in) bool: enable, false for disable suspend
 *param (in) lv_watch_Activity_Id_t: act id of app
 *param (in) bool: top, true for checking only when act is on top, false for checking whenever
 *return void
 */
void watch_set_suspend_enable(bool enable, lv_watch_Activity_Id_t act, bool top)
{
    lv_watch_suspend_t * suspend;

    printf("%s enable:%d, act: %d, top: %d\n", __FUNCTION__, enable, act, top);
    _LV_LL_READ(suspend_ll, suspend) {
        if(suspend->act == act) {
            if(enable == true) {
                _lv_ll_remove(&suspend_ll, suspend);
                lv_mem_free(suspend);
            }
            return;
        }
    }

    if(enable == false) {
        suspend = _lv_ll_ins_head(&suspend_ll);
        suspend->act = act;
        suspend->top = top;
    }
}

/**
 *get suspend enable status
 *return bool: true for suspend enable, flase for suspend disable
 */
static bool watch_get_suspend_enable(void)
{
    //check phone call status
    if(!watch_phone_suspend_check()) return false;

    //check voip call status
    if(!watch_voip_suspend_check()) return false;

#if USE_TOUCH_TRACKER
    if(touch_tracker_is_recording() || touch_tracker_is_playing()) return false;
#endif

    //check suspend act list
    lv_obj_t * top_act = lv_watch_get_top_activity_obj();
    lv_watch_activity_ext_t * ext = lv_obj_get_ext_attr(top_act);
    lv_watch_Activity_Id_t top_act_id = ext->actId;
    lv_watch_suspend_t * suspend;

    _LV_LL_READ(suspend_ll, suspend) {
        if(suspend->top == true) {
            if(suspend->act == top_act_id) return false;
        } else {
            return false;
        }
    }

    //check ...

    return true;
}

void watch_set_sleep_lcd_only(bool enable)
{
    printf("%s : %d\n", __FUNCTION__, enable);
    watch_sleep_lcd_only = enable;
}

bool watch_get_sleep_lcd_only(void)
{
    return watch_sleep_lcd_only;
}

void watch_set_lcd_status(bool wakeup)
{
    if(wakeup == watch_lcd_status) return;
    watch_lcd_status = wakeup;

    if(wakeup){
        if(Hal_ambient_flag_get() == AMBIENT_ON)
            watch_exit_ambient();
        else
            Hal_Lcd_Touch_Wakeup();
#if USE_LV_WLAN != 0
        hal_wlan_lcd_wakeup(true);
#endif
        ambient_status_set(false);
    } else {
        if(Hal_ambient_flag_get() == AMBIENT_ON) {
            Hal_Touch_Sleep();
            ambient_status_set(true);
        } else
            Hal_Lcd_Touch_Sleep();
#if USE_LV_WLAN != 0
        hal_wlan_lcd_wakeup(false);
#endif
    }
}

bool watch_get_lcd_status(void)
{
    return watch_lcd_status;
}

static void watch_normal_charging_status_change(VOID * para)
{
    (void)para;

    printf("%s\n", __FUNCTION__);
    watch_wakeup_time_reset();
#if USE_LV_WATCH_SD_AUTO_MOUNT != 0
    watch_start_sd_mount_task();
#endif
}

void watch_set_pintype(MMI_MODEM_PIN_STATUS_TYPE pinreqtype)
{
    pintype = pinreqtype;
}

MMI_MODEM_PIN_STATUS_TYPE watch_get_pintype(void)
{
    return pintype;
}

static void watch_wakeup_lcd_handler(lv_task_t * para)
{
    bool *always = (bool*)para->user_data;
    if(!(*always) && phone_is_monitor_on()) {
        return;
    }

    if(!watch_get_lcd_status()) {
        printf("%s\n", __FUNCTION__);
        watch_set_lcd_status(true);
        watch_wakeup_time_reset();
    }
}

static bool para;
void watch_wakeup_lcd(bool always)
{
    para = always;
    lv_task_t * task = lv_task_create(watch_wakeup_lcd_handler, 0, LV_TASK_PRIO_HIGHEST, (void *)&para);
    lv_task_once(task);
}

#if USE_LV_WATCH_SD_AUTO_MOUNT != 0
static void sd_mount_task_handle(lv_task_t * task)
{
    int usb_sta = Hal_Get_Usb_Status();

    if(usb_conn_status != usb_sta) {
        printf("%s:usb old status = %d, usb new status = %d, sd_user = %d\n", __FUNCTION__, usb_conn_status, usb_sta, HAL_sd_user_get());
        watch_set_lcd_status(true);
        if(HAL_USB_CONNECTED == usb_sta) {
            setting_sd_mount_on_clear_ui();
            setting_sd_mount_capture_by_usb();
        } else {
            setting_sd_mount_off_clear_ui();
            setting_sd_mount_remove();
        }
        usb_conn_status = usb_sta;
    }
}

static void watch_start_sd_mount_task(void)
{
    if(NULL == sd_mount_task) {
        sd_mount_task = lv_task_create(sd_mount_task_handle, 100, LV_TASK_PRIO_HIGH, NULL);
    }
}
#endif

void watch_set_alarm_flag(bool alarm_flag)
{
    watch_alarm_flag = alarm_flag;
}

#endif/* USE_LV_WATCH */
